﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Windows;
using Microsoft.Win32;
using System.IO;
using System.Collections;
using System.ComponentModel;
using Shoozla.View;
using Shoozla.DataModel;
using System.Diagnostics;
using System.Threading;
using System.Windows.Threading;
using Shoozla.Helper;
using System.Windows.Forms;


namespace Shoozla.ViewModel
{
    public class FolderListViewModel : ViewModelBase
    {

        #region Properties      

        #endregion

        #region Constructors
        public FolderListViewModel(System.Windows.Threading.Dispatcher dispatcher) : base(dispatcher) { }
        #endregion

        #region Commands

        private RelayCommand _CmdOpenFolder;
        public RelayCommand CmdOpenFolder
        {
            get
            {
                if (_CmdOpenFolder == null)
                {
                    _CmdOpenFolder = new RelayCommand(param => DoCmdOpenFolder(), param => CanExecuteUI());
                }
                return _CmdOpenFolder;
            }
        }

        private RelayCommand _CmdShowCovered;
        public RelayCommand CmdShowCovered
        {
            get
            {
                if (_CmdShowCovered == null)
                {
                    _CmdShowCovered = new RelayCommand(param => DoCmdShowCovered(), param => CanExecuteItemsOp());
                }
                return _CmdShowCovered;
            }
        }

        private RelayCommand _CmdShowUnCovered;
        public RelayCommand CmdShowUnCovered
        {
            get
            {
                if (_CmdShowUnCovered == null)
                {
                    _CmdShowUnCovered = new RelayCommand(param => DoCmdShowUnCovered(), param => CanExecuteItemsOp());
                }
                return _CmdShowUnCovered;
            }
        }

        private RelayCommand _CmdSearch;
        public RelayCommand CmdSearch
        {
            get
            {
                if (_CmdSearch == null)
                {
                    _CmdSearch = new RelayCommand(param => DoCmdSearch(), param => CanExecuteSearch());
                }
                return _CmdSearch;
            }
        }

        private bool CanExecuteSearch()
        {
            if (App.CurrenAppStatus == App.AppStatus.Idle && CanExecuteSelectedItemsOp())
                return true;
            else
                return false;
        }

        #endregion

        #region Do Commands

        private void DoCmdShowCovered()
        {
            CurrentItems = new MultithreadingObservableCollection<Mp3File>((
                           from f in AllItems
                           where f.HasCover == true
                           select f).ToArray<Mp3File>(), _dispatcherUIThread);
        }

        private void DoCmdShowUnCovered()
        {

            var temp = (from f in AllItems
                        where f.HasCover == false
                        select f).ToList<Mp3File>();

            CurrentItems = new MultithreadingObservableCollection<Mp3File>(temp.ToArray<Mp3File>(), _dispatcherUIThread);
        }
    
        private void DoCmdSearch()
        {

            //start the internet search
           
            App.LogEntry("Connecting to LASTFM...");
            var res = MessageBoxResult.OK;
            if (!App.lastFMsrv.LastFMInitializated)
            {
                App.lastFMsrv.InitAuth();
                //res = TaskDialogClass.TaskDialog(
                //       new System.Windows.Interop.WindowInteropHelper((Window)App.MainView).Handle,
                //       IntPtr.Zero, "Shoozla", "Shoozla is searching for covers", "You need to login to LASTFM website and authorize this App to proceed.\nGo to the LASTFM website and click on the \"Yes, allow access\" button.\n\nClick OK once done. ",
                //       TaskDialogButtons.OK | TaskDialogButtons.Cancel,
                //       TaskDialogIcon.SecurityShieldBlue
                //        );
                res = System.Windows.MessageBox.Show(App.MainView, "You need to login to LASTFM website to proceed", "Shoozla", MessageBoxButton.OKCancel, MessageBoxImage.Information);
            }
            else
                res = System.Windows.MessageBox.Show(App.MainView, "Shoozla is going to connect to LASTFM to search for covers, continue?", "Shoozla", MessageBoxButton.OKCancel, MessageBoxImage.Information);

              //  res = TaskDialogClass.TaskDialog(
              //       new System.Windows.Interop.WindowInteropHelper((Window)App.MainView).Handle,
              //       IntPtr.Zero,"Shoozla", "Shoozla is searching for covers","Alredy logged on LASTFM, continue?",
              //       TaskDialogButtons.OK | TaskDialogButtons.Cancel,
              //       TaskDialogIcon.SecurityShieldBlue
              //);

            if (res == MessageBoxResult.OK)
            {
                //clean the logging
                App.CoverSearcher = new LASTFMSearcher(App.lastFMsrv.Auth);

                App.Logger.CoversFound = 0;
                App.CoverStorage.Reset();
                App.CurrenAppStatus = App.AppStatus.SearchingCovers;
                App.lastFMsrv.InitSession();
                RaiseItemOperationStarted(SelectedItems.Count, "Searching for covers");
                App.ThreadingFactor = App.ThreadingFactorEnum.Maximum;
                App.SearchWorker = new ListWorker<Mp3File>(SelectedItems.ToList<Mp3File>(), App.CalculateTreads(SelectedItems.Count));
                App.SearchWorker.SplitAndRun(CoverSearcherWorker);
            }
        }

        private void CoverSearcherWorker(object o)
        {
            List<Mp3File> workingList = o as List<Mp3File>;
            if (workingList != null)
            {
                //var lastFMsrv = LASTFMService.GetInstance(Properties.Resources.APPKEY, Properties.Resources.SECRET);
                foreach (Mp3File mp3 in workingList)
                {
                    SearchCover( mp3);
                }
            }

        }

        public void RefreshOpenedFolder()
        {
            MainWindowViewModel mainModel = ((MainWindowViewModel)App.MainView.DataContext);
            OpenFolderInternal(mainModel.CurrentFolder.FullName);
        }

        private void DoCmdOpenFolder()
        {
            FolderBrowserDialog folderDialog = new FolderBrowserDialog();
            folderDialog.Description = "Select a folder with Mp3 files";
            var res = folderDialog.ShowDialog();
            if (res == DialogResult.OK)
            {
                //clean the logging
                OpenFolderInternal(folderDialog.SelectedPath);
            }
        }

        private void OpenFolderInternal(string folderName)
        {
            try
            {
                App.Logger.FilesProcessed = 0;

                MainWindowViewModel mainModel = ((MainWindowViewModel)App.MainView.DataContext);
                CurrentItems.Clear();

                mainModel.CurrentFolder = new DirectoryInfo(folderName);
                FileInfo[] files = mainModel.CurrentFolder.GetFiles("*.mp3", SearchOption.AllDirectories);
                App.CurrenAppStatus = App.AppStatus.ReadingFiles;
                RaiseItemOperationStarted(files.Length, "Searching for Mp3 files");//init the progress bar

                //App.ThreadingFactor = App.ThreadingFactorEnum.lazy;
                App.ThreadingFactor = App.ThreadingFactorEnum.Single;

                App.FileWorker = new ListWorker<FileInfo>(new List<FileInfo>(files), App.CalculateTreads(files.Count()));
                App.FileWorker.SplitAndRun(FileReaderWorker);
            }
            catch (UnauthorizedAccessException accEx)
            {
                App.LogEntry("[ERROR] OpenFolderInternal: " + accEx.Message);
            }
        }

        private void FileReaderWorker(object o)
        {
            List<FileInfo> workingList = o as List<FileInfo>;
            if (workingList != null)
            {
                IMP3Processor mp3Processor = new IDSharpProcessor();
                foreach (FileInfo fi in workingList)
                {
                    Mp3File song = mp3Processor.ReadID3Tag(fi.FullName);
                    if (song != null)
                    {
                        song.IsSelected = !song.HasCover; //select all "uncovered album"
                        AllItems.Add(song);
                    }
                    RaiseItemRead(false);
                }
            }

        }
        #endregion

        private void SearchCover(Mp3File song)
        {

            Uri cover = App.CoverSearcher.FindCover(song);

            if (cover != null)
            {
                song.ImageUrl = cover;
                App.CoverStorage.AddCoverToStorage(song);
                RaiseItemRead(true);
            }
            else RaiseItemRead(false);

        }

        public void EditMp3(Mp3File song)
        {
            App.SummaryView= new SummaryView(song);
            App.SummaryView.ShowDialog();
        }
    }
}
